#pragma once

#include "Protocol.hpp"
#include "Calculator.hpp"
#include "Log.hpp"
#include <iostream>
#include <functional>

using handler_t = std::function<Response (Request &ret)>;

class Parser
{
public:
    Parser(handler_t handler): _handler(handler) 
    {}

    // 只对报文进行解析工作, 请求和应答工作不做处理
    std::string Parse(std::string &inbuffer)
    {
        std::string send_str;
        // 接收到的字符串中不仅仅只有一条报文, 要将其中所有的报文都提取出来
        while (true)
        {
            std::string jsonstr;
            int n = Protocol::Unpack(inbuffer, &jsonstr);
            if (n < 0)
            {
                LOG(LogLevel::FATAL) << "报文格式错误";
                exit(0);
            }
            else if (n == 0)
            {
                LOG(LogLevel::INFO) << "报文已全部解析";
                break;
            }
            else
            {
                // 反序列化
                Request req;
                if (!req.Deserialize(jsonstr))
                {
                    LOG(LogLevel::WARING) << "反序列化失败";
                    return std::string();
                }
                LOG(LogLevel::INFO) << "反序列化成功";

                // 实现具体业务: _x oper _y = ret
                Response ret = _handler(req);

                // 将计算结果序列化
                std::string ret_jsonstr;
                if (!ret.Serialize(&ret_jsonstr))
                {
                    return std::string();
                }

                // 封装报文
                send_str += Protocol::Package(ret_jsonstr); // 发送给对端
            }
        }
        // 发回给对端
        return send_str;
    }
    ~Parser() {}
private:
    handler_t _handler;
};